import { _decorator, Component, director, JsonAsset, Label, ProgressBar, SceneAsset } from 'cc';
import { BasePrefab, LoadingBundle } from '../Basic/Config/BaseEnum';
import { LoadingManager } from '../Basic/Manager/LoadingManager';
import { Tables } from '../Data/Types';
import { GameManager } from '../Basic/Manager/GameManager';
import { LogUtil } from '../Util/LogUtil';
import { MenuModel } from '../Game/Menu/MenuModel';
import { OpenLoadModel } from '../Basic/UI/OpenLoadPanel';
import { DataMgr } from '../Basic/Manager/DataManager';
import { CallBackHandler } from '../Basic/Model/PoolObj/CallBackHandler';
import { GameScene } from './GameScene';
const { ccclass, property } = _decorator;

@ccclass('LoadScene')
export class LoadScene extends Component {
  @property(ProgressBar)
  bar: ProgressBar = null!;
  @property(Label)
  barLab: Label = null!;
  @property
  speed: number = 1;
  @property
  toFixed: number = 0;

  private stepRate: number = 0;
  private tempRate: number = 0;
  private loadingRate: number = 0;
  private loadingRateMax: number = 0;
  // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
  private stepFuncs: Function[] = [];
  protected onEnable(): void {
    this.bar.progress = 0;
    this.barLab.string = '0%';
    this.stepRate = 0;
    this.tempRate = 0;
    this.loadingRate = 0;

    this.stepFuncs = [this.loadBundle, this.loadTables, this.initTables, this.loadGameRes, this.initScene, this.Complete];
    this.loadingRateMax = this.stepFuncs.length;
    this.stepFuncs[this.stepRate].call(this);
  }

  protected update(dt: number): void {
    if (this.stepRate >= this.loadingRateMax) return;
    if (this.tempRate < this.loadingRate) {
      this.tempRate += dt * this.speed;
      if (this.tempRate > this.loadingRate) {
        this.tempRate = this.loadingRate;
      }
    } else {
      return;
    }
    const rate = (this.stepRate + this.tempRate) / this.loadingRateMax;
    this.barLab.string = `${(rate * 100).toFixed(this.toFixed)}%`;
    this.bar.progress = rate > 1 ? 1 : rate;
    if (this.tempRate >= 1 && this.loadingRate >= 1) {
      this.tempRate = 0;
      this.loadingRate = 0;
      this.stepRate++;
      if (this.stepRate < this.loadingRateMax) {
        this.stepFuncs[this.stepRate].call(this);
      }
    }
  }

  protected onProgress = (rate) => {
    this.loadingRate = rate;
  };

  /** 加载资源包 */
  private loadBundle() {
    LogUtil.i('加载资源包......');
    const bundles = [LoadingBundle.PublicBundle, LoadingBundle.MainGameBundle, LoadingBundle.GameBundle, LoadingBundle.SceneBundle];
    LoadingManager.Ins().loadBundle(bundles, this.onProgress.bind(this));
  }

  /** 加载表数据 */
  private loadTables() {
    LogUtil.i('加载表数据......');
    const bundle = LoadingManager.Ins().getBundle(LoadingBundle.PublicBundle);
    const arr = bundle.getDirWithPath('data');
    const loadRes = [];
    for (let i = 0; i < arr.length; i++) {
      // loadRes.push(LoadingBundle.publicBundle + '/' + arr[i].path);
      loadRes.push(arr[i].path);
    }
    LoadingManager.Ins().loadResByBundle(LoadingBundle.PublicBundle, loadRes, this.onProgress.bind(this));
  }

  /** 初始化表数据，链接服务器 */
  private initTables() {
    LogUtil.i('初始化表数据，链接服务器......');
    // const task = Task.createSync();
    // task.add((next) => {
    DataMgr.tables = new Tables(this.loadTable);
    // next();
    // });
    // task.add((next) => {
    this.initServerData();
    // next();
    // });
    // task.start(this.onProgress.bind(this, 1));
    this.onProgress(1);
  }

  /** 加载主界面资源，初始化游戏场景 */
  private loadGameRes() {
    LogUtil.i('加载主界面资源，初始化游戏场景......');
    const loadRes = [
      MenuModel.Ins().loadRes,
      //通用加载界面资源
      OpenLoadModel.Ins().loadRes,
      //UI控制器
      BasePrefab.ui_controller,
    ];
    LoadingManager.Ins().loadResource(loadRes, this.onProgress);
  }

  /** 加载场景 */
  private initScene() {
    LogUtil.i('加载场景......');
    LoadingManager.Ins().loadScene('GameScene', CallBackHandler.pop(this.initGameData, this));
  }

  /** 通过表、服务器数据，初始化游戏内数据 */
  private async initGameData(sceneAsseet: SceneAsset) {
    LogUtil.i('初始化游戏数据......');
    const sceneSp: GameScene = sceneAsseet.scene.getChildByName('GameScene').getComponent(GameScene);
    await sceneSp.initGameScene();
    this.onProgress(1);
  }

  /** 获取服务器数据 */
  private initServerData() {
    //设置时间控制器
    GameManager.Singleton.init();
  }

  /** 加载表格数据 */
  loadTable(jsonName: string) {
    const str = LoadingBundle.PublicBundle + '/data/' + jsonName;
    const bundle: JsonAsset = LoadingManager.Ins().getResource<JsonAsset>(str);
    return bundle.json;
  }

  private async Complete() {
    director.runScene(await LoadingManager.Ins().getLoadScene('GameScene'));
  }
}
